package blue.web.dao.service;


import blue.commons.models.KeyValue;
import blue.dao.uploadexcel.ExcelVirtualGroup;
import blue.tools.constants.BlueContants;
import blue.commons.enums.StatusEnum;
import blue.commons.enums.UserTypeEnum;
import blue.dao.base.BaseMapper;
import blue.dao.uploadexcel.ExcelAccountStudent;
import blue.dao.uploadexcel.ExcelAccountTeacher;
import blue.dao.utils.SysUserUtils;
import blue.erp.dao.SysUserMapper;
import blue.erp.model.*;
import blue.tools.commons.BlueStringUtils;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.promeg.pinyinhelper.Pinyin;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class SysUserService extends BaseService{

    @Resource
    private SysUserMapper sysUserMapper;

    @Autowired
    private BlueSchoolService blueSchoolService;

    @Autowired
    private BlueGradeService blueGradeService;

    @Autowired
    private BlueClassService blueClassService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private BlueStudentService blueStudentService;

    @Autowired
    private BlueTeacherService blueTeacherService;

    @Autowired
    private BlueCourseService blueCourseService;


    public int deleteBatch(String ids,Long schoolId) {

        List idList= BlueStringUtils.convertString2Num(ids,",");
        SysUserExample example=new SysUserExample();
        example.createCriteria().andIdIn(idList).andSchoolidEqualTo(schoolId);

        //删除教师关联表
        blueTeacherService.deleteByUserIds(ids,schoolId);
        //删除学生关联表
        blueStudentService.deleteByUserIds(ids,schoolId);
        clearCache(schoolId);
        return this.getBaseMapper().deleteByExample(example);
    }


    public int save(SysUser record) {

        if(record==null || (record.getId()==null && StringUtils.isBlank(record.getRealName()))){
            return 0;
        }

        record=addPropertyWhenCreate(record,false);

        SysUserExample example=new SysUserExample();
        SysUserExample.Criteria criteria=example.createCriteria().andSchoolidEqualTo(record.getSchoolid());

        if(record.getId()!=null && record.getId().longValue()>0){
            criteria.andIdEqualTo(record.getId());
        }

        if(StringUtils.isNotBlank(record.getUserno())){
            criteria.andUsernoEqualTo(record.getUserno());
        }

        if(StringUtils.isBlank(record.getUserno()) && StringUtils.isNotBlank(record.getUsername())){
            criteria.andUsernameEqualTo(record.getUsername());
        }

        if(StringUtils.isBlank(record.getRealName())){//防止姓名被前端不小心删除
            record.setRealName(null);
        }

        int result=this.baseSave(record,example);

        //增加子类型表数据
        if(result>0 && StringUtils.isNotBlank(record.getRoleIds())){
            String[] roleIds=record.getRoleIds().split(",");
            if(roleIds.length>0){
                for(String roleId:roleIds){
                    SysRole sysRole=sysRoleService.selectById(Long.decode(roleId),record.getSchoolid(),false);
                    if(sysRole==null){
                        continue;
                    }

                    switch (sysRole.getName()){
                        case BlueContants.special_role_student:
                            BlueStudent blueStudent=SysUserUtils.convert2Student(record);
                            blueStudent.setStatus((byte) StatusEnum.Normal.getValue());
                            blueStudentService.save(blueStudent);
                            break;
                        case BlueContants.special_role_teacher:
                            BlueTeacher blueTeacher=SysUserUtils.convert2Teacher(record);
                            blueTeacher.setStatus((byte) StatusEnum.Normal.getValue());
                            blueTeacherService.save(blueTeacher);
                            break;
                    }

                }
            }
        }

        return result;

    }

    /**
     *
      * @param classId
     * @param schoolId
     * @param type 1:查询class的数据信息,2:group
     * @return
     */
    public long getStudentCountOfClass(Long classId,Long schoolId,int type ){
//        Object cacheObject=redisService.getValue(String.format("%s_%s_%s",BlueContants.prefix_studentCount,schoolId,classId));
//        if(cacheObject!=null){
//            return Long.decode(cacheObject.toString());
//        }else {
            Long count=0L;
            SysUserExample example=new SysUserExample();
            SysUserExample.Criteria criteria=example.createCriteria().andSchoolidEqualTo(schoolId).andClassIdsLike("%"+classId+"%").andTypeEqualTo((byte) UserTypeEnum.Student.getKey());
            if(type==1 || type==3){
                count=sysUserMapper.countByExample(example);
            }

            if(count==0 && type!=1){
                SysUserExample groupExample=new SysUserExample();
                groupExample.createCriteria().andSchoolidEqualTo(schoolId).andTypeEqualTo((byte) UserTypeEnum.Student.getKey()).andGroupIdsLike("%"+classId+"%");
                List<SysUser> sysUserList=this.select(groupExample);
                if(CollectionUtils.isNotEmpty(sysUserList)){
                    for(SysUser sysUser:sysUserList){
                        if(BlueStringUtils.convertString2Num(sysUser.getGroupIds(),",").contains(classId)){
                            count++;
                        }
                    }
                }
            }
//            redisService.setValue(String.format("%s_%s_%s",BlueContants.prefix_studentCount,schoolId,classId),count==null?"0":count.toString());
            return count;
//        }
    }



    public int createAccount(SysUser record){

        if(record==null || StringUtils.isBlank(record.getRealName())){
            return 0;
        }

        //增加用户登录账号
        BlueSchool blueSchool= JSONObject.parseObject(blueSchoolService.baseSelectByPrimaryKey(record.getSchoolid(),
                BlueContants.prefix_schoolInfo,record.getSchoolid(),false, BlueContants.year).toString(),BlueSchool.class);

        String pinyin=Pinyin.toPinyin(record.getRealName(),"").toLowerCase();

        record.setUsername(String.format("%s.%s",pinyin,blueSchool.getUsernameSuffix()));

        if(!isCreateAccountSuccess(record)){
            for(int i=1;i<100;i++){
                record.setUsername(String.format("%s%02d.%s",pinyin,i,blueSchool.getUsernameSuffix()));
                if(isCreateAccountSuccess(record)){
                    break;
                }
            }
        }

        record.setStatus((byte) StatusEnum.Normal.getValue());
        record=addPropertyWhenCreate(record,true);

        return this.save(record);

    }


    private boolean isCreateAccountSuccess(SysUser record){

        SysUserExample example=new SysUserExample();
        example.createCriteria().andUsernameEqualTo(record.getUsername()).andSchoolidEqualTo(record.getSchoolid());
        List<SysUser> sysUserList=this.select(example);

        if(CollectionUtils.isEmpty(sysUserList)){
            return true;
        }

        return false;

    }


    public SysUser selectByLoginName(String loginName) {

        if(StringUtils.isBlank(loginName)){
            return null;
        }

        SysUserExample example=new SysUserExample();
        example.createCriteria().andUsernameEqualTo(loginName);

        List<SysUser> sysUsers=this.select(example);

        if(CollectionUtils.isNotEmpty(sysUsers) && sysUsers.size()==1){
            return sysUsers.get(0);
        }

        return null;
    }

    public SysUser selectByUserNo(String userNo,Long schoolId) {

        if(StringUtils.isBlank(userNo) || schoolId==null){
            return null;
        }

        SysUserExample example=new SysUserExample();
        example.createCriteria().andUsernoEqualTo(userNo).andSchoolidEqualTo(schoolId);

        List<SysUser> sysUsers=this.select(example);

        if(CollectionUtils.isNotEmpty(sysUsers) && sysUsers.size()==1){
            return sysUsers.get(0);
        }

        return null;
    }


    public SysUser addPropertyWhenCreate(SysUser record, boolean addPassword) {

        if (record == null) {
            return null;
        }

        //增加账号密码，修改的时候，不应该修改salt，只有创建的时候需要
        if (record.getId()==null && StringUtils.isBlank(record.getSalt())) {
            record.setSalt(RandomUtil.randomString(32));
        }

        if (addPassword) {
            if (StringUtils.isBlank(record.getPassword())) {
                record.setPassword(getInitPassWord(record));
            }
            SimpleHash simpleHash = new SimpleHash("md5", record.getPassword(), ByteSource.Util.bytes(record.getSalt()), 2);
            record.setPassword(simpleHash.toString());
        }


        return record;
    }


    public int createStudentAccountByExcel(List<ExcelAccountStudent> excelAccountStudentList,Long schoolId){
        int result=0;

        if(CollectionUtils.isEmpty(excelAccountStudentList) || schoolId==null || schoolId.longValue()<=0){
            return 0;
        }
        for(ExcelAccountStudent excelAccountStudent:excelAccountStudentList){
            SysUser sysUser=JSONObject.parseObject(JSONObject.toJSONString(excelAccountStudent),SysUser.class);
            sysUser.setSchoolid(schoolId);
            //年级处理
            if(StringUtils.isBlank(excelAccountStudent.getGradeName())
                    || StringUtils.isBlank(excelAccountStudent.getGrade()) || StringUtils.isBlank(excelAccountStudent.getClassName())){
                continue;
            }

            BlueGrade blueGrade=addGradeByCreateAccount(excelAccountStudent.getGradeName(),excelAccountStudent.getGrade(),schoolId);

            //班级处理
            sysUser=addClassByCreateAccount(excelAccountStudent.getGradeName(),excelAccountStudent.getClassName(),blueGrade,schoolId,sysUser);


            //角色处理
            sysUser=handleRoleByCreateAccount(sysUser,"学生",schoolId);
            sysUser.setType((byte) UserTypeEnum.Student.getKey());
            result+=createAccount(sysUser);


        }

        return result;
    }

    public int createVirtualGroupByExcel(List<ExcelVirtualGroup> excelVirtualGroupList,SysUser sysUser){
        int result=0;
        if(CollectionUtils.isEmpty(excelVirtualGroupList) || sysUser.getSchoolid()==null){
            return result;
        }

        for(ExcelVirtualGroup excelVirtualGroup:excelVirtualGroupList){

            if(StringUtils.isBlank(excelVirtualGroup.getGroupIds())){
                continue;
            }

            BlueClass blueClass=blueClassService.selectByPrimaryKey(Long.decode(excelVirtualGroup.getGroupIds()),sysUser.getSchoolid(),false);
            if(blueClass==null){
                continue;
            }

            if(StringUtils.isNotBlank(excelVirtualGroup.getGroupIds())){
                SysUser itemUser=this.selectByUserNo(excelVirtualGroup.getUserno(),sysUser.getSchoolid());
                if(itemUser!=null){
                    List groupList=BlueStringUtils.convertString2Num(itemUser.getGroupIds(),",");
                    if(groupList.contains(blueClass.getId())){
                        continue;
                    }
                    groupList.add(blueClass.getId());
                    itemUser.setGroupIds(StringUtils.join(groupList,","));

                    //给教师增加班级属性
                    if(UserTypeEnum.Teacher.getKey()==itemUser.getType()){
                        BlueTeacher blueTeacher=new BlueTeacher();
                        blueTeacher.setUserid(itemUser.getId());
                        blueTeacher.setSchoolid(sysUser.getSchoolid());
                        List<BlueTeacher> blueTeacherList=blueTeacherService.select(blueTeacher);
                        if(CollectionUtils.isNotEmpty(blueTeacherList) && blueTeacherList.size()==1){
                            blueTeacher=blueTeacherList.get(0);
                            List classIds=BlueStringUtils.convertString2Num(blueTeacher.getClassids(),",");
                            if(CollectionUtils.isEmpty(classIds)){
                                classIds=new LinkedList();
                            }

                            classIds.addAll(groupList);
                            Set<String> set = new HashSet<>(classIds);
                            blueTeacher.setClassids(StringUtils.join(set,","));
                            blueTeacherService.save(blueTeacher);
                        }
                    }

                    result+=this.getBaseMapper().updateByPrimaryKeySelective(itemUser);
                }
            }
        }

        return result;
    }


    public int createTeacherAccountByExcel(List<ExcelAccountTeacher> excelAccountTeacherList, Long schoolId){
        int result=0;

        if(CollectionUtils.isEmpty(excelAccountTeacherList) || schoolId==null || schoolId.longValue()<=0){
            return 0;
        }
        for(ExcelAccountTeacher excelAccountTeacher:excelAccountTeacherList){
            SysUser sysUser=JSONObject.parseObject(JSONObject.toJSONString(excelAccountTeacher),SysUser.class);
            sysUser.setSchoolid(schoolId);

            BlueGrade blueGrade=addGradeByCreateAccount(excelAccountTeacher.getGradeName(),excelAccountTeacher.getGrade(),schoolId);

            sysUser= addClassByCreateAccount(excelAccountTeacher.getGradeName(),excelAccountTeacher.getClassName(),blueGrade,schoolId,sysUser);

            //角色处理
            sysUser= handleRoleByCreateAccount(sysUser,"教师",schoolId);
            sysUser.setType((byte) UserTypeEnum.Teacher.getKey());

            if(StringUtils.isNotBlank(excelAccountTeacher.getCourseNames())){
                List courseIdList=new LinkedList();
                String[] courseNames=excelAccountTeacher.getCourseNames().split(BlueContants.separator);
                for(String courseName:courseNames){
                    BlueCourse blueCourse=addCourseByCreateAccount(courseName,excelAccountTeacher.getGrade(),schoolId);
                    if(blueCourse!=null && blueCourse.getId()!=null){
                        courseIdList.add(blueCourse.getId());
                    }
                }

                if(CollectionUtils.isNotEmpty(courseIdList)){
                    sysUser.setCourseIds(StringUtils.join(courseIdList,BlueContants.separator));
                }
            }


            result+=createAccount(sysUser);
        }

        return result;
    }


    private BlueGrade addGradeByCreateAccount(String gradeName,String grade,Long schoolId){

        if(StringUtils.isBlank(gradeName)){
            return null;
        }

        BlueGrade blueGrade=blueGradeService.selectedByName(gradeName,schoolId,false);
        if(blueGrade==null){
            blueGrade=new BlueGrade();
            blueGrade.setSchoolid(schoolId);
            blueGrade.setName(gradeName);
            blueGrade.setGradeLevel(grade);
            blueGrade.setStatus((byte) StatusEnum.Normal.getValue());
            blueGrade.setCreateTime(new Date());
            blueGrade.setUpdateTime(new Date());
            blueGradeService.getBaseMapper().insert(blueGrade);
        }

        return blueGrade;
    }


    private BlueCourse addCourseByCreateAccount(String courseName,String type,Long schoolId){

        if(StringUtils.isBlank(courseName)){
            return null;
        }

        BlueCourse blueCourse=blueCourseService.selectedByName(courseName,null,schoolId,false);
        if(blueCourse==null){
            blueCourse=new BlueCourse();
            blueCourse.setSchoolid(schoolId);
            blueCourse.setName(courseName);
            blueCourse.setStatus((byte) StatusEnum.Normal.getValue());
            blueCourse.setCreateTime(new Date());
            blueCourse.setUpdateTime(new Date());
            blueCourseService.getBaseMapper().insert(blueCourse);

        }

        return blueCourse;
    }


    private SysUser addClassByCreateAccount(String gradeName,String className,BlueGrade blueGrade,Long schoolId,SysUser sysUser){

        if(StringUtils.isBlank(gradeName) || StringUtils.isBlank(className)){
            return sysUser;
        }

        BlueClass blueClass=new BlueClass();
        blueClass.setName(className);
        blueClass.setGradeName(gradeName);
        blueClass.setGradeid(blueGrade.getId());
        blueClass.setSchoolid(schoolId);
        List<Long> gradeList=new LinkedList();
        gradeList.add(blueGrade.getId());
        List<BlueClass> blueClassList=blueClassService.selectByBlueClass(blueClass,gradeList,false);
        if(CollectionUtils.isEmpty(blueClassList)){
            blueClass.setStatus((byte) StatusEnum.Normal.getValue());
            blueClassService.save(blueClass);
            blueClassList=blueClassService.selectByBlueClass(blueClass,gradeList,false);
        }
        sysUser.setGradeIds(blueGrade.getId().toString());
        sysUser.setClassIds(blueClassList.get(0).getId().toString());

        return sysUser;
    }

    private SysUser handleRoleByCreateAccount(SysUser sysUser,String roleName,Long schoolId){
        SysRole sysRole=new SysRole();
        sysRole.setName(roleName);
        sysRole.setSchoolid(schoolId);
        List<SysRole> sysRoleList=sysRoleService.getRoles(sysRole,false);
        if(CollectionUtils.isNotEmpty(sysRoleList)){
            sysRole.setId(sysRoleList.get(0).getId());
        }


        sysUser.setRoleIds(sysRole.getId()==null?null:sysRole.getId().toString());

        return sysUser;
    }


    public String getInitPassWord(SysUser sysUser){
        String password=StringUtils.EMPTY;
        if(sysUser==null || StringUtils.isBlank(sysUser.getUsername())){
            return null;
        }

        password=sysUser.getUsername();

        if(StringUtils.isNotBlank(sysUser.getMobile())){
            String mobile=sysUser.getMobile();
            password+=mobile.substring(mobile.length()-4,mobile.length());
        }

        return password;
    }


    public List<SysUser> select(SysUser record){

        SysUserExample example=new SysUserExample();
        SysUserExample.Criteria criteria=example.createCriteria().andSchoolidEqualTo(record.getSchoolid());

        if(StringUtils.isNotBlank(record.getClassIds()) && !"-1".equalsIgnoreCase(record.getClassIds())){
            criteria.addCriterion(String.format("( class_ids like \"%%%s%%\" or group_ids like \"%%%s%%\")",record.getClassIds(),record.getClassIds()));
        }

        if(StringUtils.isNotBlank(record.getGradeIds()) && !"-1".equalsIgnoreCase(record.getGradeIds())){
            criteria.andGradeIdsLike("%"+record.getGradeIds()+"%");
        }

        if(StringUtils.isNotBlank(record.getRealName())){
            criteria.andRealNameLike("%"+record.getRealName()+"%");
        }

        if(StringUtils.isNotBlank(record.getRoleIds())){
            criteria.andRoleIdsEqualTo(record.getRoleIds());
        }

        if(record.getType()!=null && record.getType()!=null){
            criteria.andTypeEqualTo(record.getType());
        }

        if(StringUtils.isNotBlank(record.getUserno())){
            criteria.andUsernoEqualTo(record.getUserno());
        }

        List<SysUser> sysUserList=this.select(example);
        if(CollectionUtils.isEmpty(sysUserList)){
            return null;
        }


        for(SysUser sysUser:sysUserList){
            addPropertyNameById(sysUser);
        }

        return sysUserList;
    }

    /**
     * 根据
     * @param record
     * @return
     */
    public SysUser addPropertyNameById(SysUser record){

        if(record==null ){
            return null;
        }

        if(StringUtils.isNotBlank(record.getRoleIds())){
            List roleList=new LinkedList();

            for(Long roleId:BlueStringUtils.convertString2Num(record.getRoleIds(),",")){
                SysRole sysRole=sysRoleService.selectById(roleId,record.getSchoolid(),false);

                if(sysRole!=null){
                    roleList.add(new KeyValue(sysRole.getId(),sysRole.getName()));
                }
            }

            record.setRoles(roleList);
        }

        if(StringUtils.isNotBlank(record.getClassIds())){
            List classList=new LinkedList();
            for(Long classId:BlueStringUtils.convertString2Num(record.getClassIds(),",")){
                BlueClass blueClass=blueClassService.selectByPrimaryKey(classId,record.getSchoolid(),false);
                if(blueClass!=null){
                    classList.add(new KeyValue(blueClass.getId(),blueClass.getName()));
                }
            }

            record.setClasses(classList);

        }

        if(StringUtils.isNotBlank(record.getGroupIds())){
            List<Long> groupIdList=BlueStringUtils.convertString2Num(record.getGroupIds(),",");
            List<KeyValue> keyValueList=new LinkedList<>();
            if(CollectionUtils.isNotEmpty(groupIdList)){
                for(Long classId:groupIdList){
                    BlueClass blueClass=blueClassService.selectByPrimaryKey(classId,record.getSchoolid(),false);
                    if(blueClass!=null){
                        KeyValue keyValue=new KeyValue();
                        keyValue.setKey(blueClass.getId());
                        keyValue.setValue(blueClass.getName());
                        keyValueList.add(keyValue);
                    }
                }
                record.setGroups(keyValueList);
            }
        }

        if(StringUtils.isNotBlank(record.getGradeIds())){
            List gradeList=new LinkedList();
            for(Long gradeId:BlueStringUtils.convertString2Num(record.getGradeIds(),",")){
                BlueGrade blueGrade=blueGradeService.selectByPrimaryKey(gradeId,record.getSchoolid(),false);
                if(blueGrade!=null){
                    gradeList.add(new KeyValue(blueGrade.getId(),blueGrade.getName()));
                }
            }
            record.setGrades(gradeList);
        }

        return record;

    }


    public int changePassword(SysUser sysUser,String oldPassWord,boolean forceChange){
       if(sysUser==null || StringUtils.isBlank(sysUser.getPassword()) || sysUser.getId()==null){
           return 0;
       }

       //校验旧密码是否正确
       if(!forceChange){
           SysUser oldUser= (SysUser) this.selectByPrimaryKey(sysUser.getId(),sysUser.getSchoolid());
           if(!checkedPassword(oldPassWord,oldUser.getSalt(),oldUser.getPassword())){
               return -1;
           }
       }
       sysUser.setSalt(RandomUtil.randomString(32));
       addPropertyWhenCreate(sysUser,true);
       return this.save(sysUser);
    }

    public boolean checkedPassword(String rawPasword,String salt,String md5Password){
        if(StringUtils.isBlank(rawPasword)||StringUtils.isBlank(md5Password)){
            return false;
        }

        SimpleHash simpleHash = new SimpleHash("md5", rawPasword, ByteSource.Util.bytes(salt), 2);

        if(md5Password.equals(simpleHash.toString())){
            return true;
        }

        return false;
    }

    @Override
    public BaseMapper getBaseMapper() {
        return this.sysUserMapper;
    }

    @Override
    public void clearCache(Long schoolId,Object... extend) {
//        redisService.getValue(BlueContants.prefix_studentCount+schoolId);
    }
}
